﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GameData;

namespace Project1
{
    class Level
    {
        public Background bg;
        public Vector2 screen_size;
        public Boss levelBoss;
        public Enemy[] enemyList;
        public double[] enemyTime;
        private int minEnemy;
        private int currentEnemy;
        // public Terrain[] terrainList;
        // public double[] terrainTime;
        // private int minTerrain;
        // private int currentTerrain;
        private int minPowerup;
        private int currentPowerup;
        public Powerup[] powerupList;
        public double[] powerupTime;

        public double currentTime;
        public bool active;
        public bool spawnedBoss;

        public Level(Texture2D bgTex, Vector2 screen)
        {
            bg = new Background( bgTex, screen );
            bg.vel = new Vector2(-50.0f, 0.0f);
            screen_size = screen;
            enemyList = new Enemy[0];
            enemyTime = new double[0];
            minEnemy = currentEnemy = 0;
            // terrainList = new Terrain[0];
            // terrainTime = new double[0];
            // minTerrain = currentTerrain = 0;
            

            currentTime = 0;
            active = false;
            spawnedBoss = false;
        }

        public Level(Texture2D bgTex, Vector2 screen, Enemy[] eList, double[] eTime)
        {
            bg = new Background(bgTex, screen);
            bg.vel = new Vector2(-50.0f, 0.0f);
            screen_size = screen;
            enemyList = new Enemy[eList.Length];
            enemyTime = new double[eTime.Length];
            for (int i = 0; i < eList.Length; i++)
            {
                enemyList[i] = eList[i];
                enemyTime[i] = eTime[i];
            }
            minEnemy = currentEnemy = 0;
            // minTerrain = currentTerrain = 0;
            // enemyList = eList.CopyTo(enemyList, 0);
            
            // terrainList = new Terrain[0];
            // terrainTime = new double[0];
            currentTime = 0;
            active = false;
            spawnedBoss = false;
        }

        public void update(double elapsedTime, PlayerShip ps)
        {
            if (!active)
                return;
            currentTime += elapsedTime;
            bg.update(elapsedTime);
            if (enemyTime[currentEnemy] <= currentTime && currentEnemy < enemyList.Length - 1)
            {
                Console.WriteLine("Spawning Enemy # " + currentEnemy + " at time " + currentTime );
                enemyList[currentEnemy].alive = true;
                enemyList[currentEnemy].target = ps.pos;
                currentEnemy++;
            }

            if (currentEnemy >= enemyList.Length)
            {
                if (!spawnedBoss)
                {
                    // spawn the boss
                }
            }

            // Check collisions
            for (int i = minEnemy; i < currentEnemy; i++)
            {
                for (int j = 0; j < ps.bullet_container.Count; j++ )
                {
                    if (enemyList[i].alive && ps.bullet_container[j].alive)
                    {
                        if (enemyList[i].collides(ps.bullet_container[j]))
                        {
                            enemyList[i].hp -= ps.bullet_container[j].damage;
                            ps.bullet_container.RemoveAt(j);
                            if (enemyList[i].hp <= 0)
                            {
                                enemyList[i].alive = false;
                            }
                        }
                    }
                }
            }

            for (int i = minEnemy; i < currentEnemy; i++)
            {
                if (enemyList[i].alive)
                {
                    enemyList[i].update(elapsedTime);
                    if (enemyList[i].collides(ps))
                    {
                        Console.WriteLine("Player crashed into enemy");
                        enemyList[i].alive = false;
                    }
                }
                for (int j = 0; j < enemyList[i].shots.Count; j++)
                {
                    if (enemyList[i].shots[j].collides(ps))
                    {
                        Console.WriteLine("Player was hit!");
                        enemyList[i].shots.RemoveAt(j);
                    }
                }
                if (enemyList[i].alive)
                {
                    if (enemyList[i].pos.X <= 0 && enemyList[i].vel.X < 0)
                        enemyList[i].alive = false;
                    if (enemyList[i].pos.X >= 800 && enemyList[i].vel.X > 0)
                        enemyList[i].alive = false;
                    if (enemyList[i].pos.Y <= 0 && enemyList[i].vel.Y < 0)
                        enemyList[i].alive = false;
                    if (enemyList[i].pos.Y >= 640 && enemyList[i].vel.Y > 0)
                        enemyList[i].alive = false;
                }
            }

            if (currentPowerup < powerupList.Length)
            {
                if (powerupTime[currentPowerup] <= currentTime && currentPowerup < powerupList.Length)
                {
                    powerupList[currentPowerup].alive = true;
                    currentPowerup++;
                }
            }

            for (int i = minPowerup; i < currentPowerup; i++)
            {
                if (powerupList[i].collides(ps))
                {
                    ps.secondaryWeapon = powerupList[i].powerup_type;
                    ps.primaryWeapon = 1;
                    if (ps.secondaryWeapon != 2)
                        ps.bullet_timer = GlobalState.Bullet_Delay_Max;
                    powerupList[i].alive = false;
                }
            }

            for (int i = minPowerup; i < currentPowerup; i++)
            {
                if (powerupList[i].alive)
                    powerupList[i].update(elapsedTime);
            }

            
            int min = minEnemy;
            while( currentTime >= enemyTime[min] && !enemyList[min].alive && min<currentEnemy){
                min++;
            }
            minEnemy = min;
        }

        public void draw(SpriteBatch sb)
        {
            if (!active)
                return;
            bg.draw(sb);
            for (int i = minEnemy; i < currentEnemy; i++)
            {
                if (enemyList[i].alive)
                    enemyList[i].draw(sb);
            }
        }

        public void start()
        {
            active = true;
            bg.alive = true;
        }

        public void createPowerups(Powerup[] pList)
        {
            //powerupList = new Powerup[leveldat.Length];
            powerupList = pList;
            powerupTime = new double[powerupList.Length];
            for (int i = 0; i < powerupList.Length; i++)
            {
                //Powerup p = powerupList[i];
                //powerupList[i].pos = new Vector2(800, 100);
                powerupList[i].spawn_time += 1 + i;
                powerupTime[i] = powerupList[i].spawn_time;

            }
        }

        public void createEnemy( ContentManager content, LevelData[] leveldat)
        {
            enemyList = new Enemy[leveldat.Length];
            enemyTime = new double[leveldat.Length];
            for (int i = 0; i < leveldat.Length; i++)
            {
                Texture2D enemyTex = content.Load<Texture2D>(leveldat[i].type);
                Vector2 startPos = new Vector2((float)leveldat[i].xpos, (float)leveldat[i].ypos);
                enemyList[i] = new Enemy(enemyTex, startPos, leveldat[i].path, leveldat[i].health);
                enemyList[i].bullet = content.Load<Texture2D>("bullet");
                enemyTime[i] = leveldat[i].time;
            }
        }
    }
}
